﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace fes
{
    // Chande Momentum Oscillator
    // http://www.mbank.pl/indywidualny/inwestycje/emakler/encyklopedia/WSKAZNIKI/cmo.html
    // http://www.nobletrading.com/blogs/2009/10/chande-momentum-oscillator-or-cmo.html
    class CMO : Indicator, IIndicator
    {
        private int n;
        private double currentValue = -1;
        private List<double> closePrices;

        public CMO(Dictionary<String, Object> parameters) : base("CMO")
        {
            base.setInidicatorParams(parameters);
            n = (int) parameters["n"] + 1;
            closePrices = new List<double>();
        }

        public void setParameters(Dictionary<String, Object> parameters)
        {
            base.setInidicatorParams(parameters);
            n = (int)parameters["n"] + 1;
        }

        public override double getValue()
        {
            return currentValue;
        }

        public override void pushNextDayData(double open, double high, double low, double close, int vol)
        {
            closePrices.Add(close);
            if (closePrices.Count > n)
            {
                closePrices.RemoveAt(0);
            }
            calculateCMO();
        }

        private void calculateCMO()
        {
            int cnt = 0;
            double upSum = 0;
            double downSum = 0;
            double chandeMomentumOscillator = 0;

            if (closePrices.Count == n)
            {
                cnt = closePrices.Count;
                for (int i = 1; i < cnt; i++)
                {
                    if (closePrices[i] >= closePrices[i - 1])
                    {
                        upSum = upSum + (closePrices[i] - closePrices[i - 1]);
                    }
                    else
                    {
                        downSum = downSum + (closePrices[i - 1] - closePrices[i]);
                    }
                }
                chandeMomentumOscillator = ((upSum - downSum) / (upSum + downSum)) * 100;
                currentValue = chandeMomentumOscillator;
            }
            else
            {
                currentValue = -1;
            }
        }
    }
}
